import sys
import service
import uix
import uiutil
import mathUtil
import uthread
import blue
import form
import xtriui
import nodemanager
import turret
import gasHarvester
import log
import trinity
import util
import uicls
import uiconst
import audio2
from math import sin, cos, tan, pi, sqrt

class StationSvc(service.Service):
    __guid__ = 'svc.station'
    __sessionparams__ = []
    __update_on_reload__ = 0
    __exportedcalls__ = {'GetGuests': [],
     'IsGuest': [],
     'GetActiveShip': [],
     'Setup': [],
     'Exit': [],
     'GetSvc': [],
     'LoadSvc': [],
     'GiveHint': [],
     'ClearHint': [],
     'GetLobby': [],
     'GetStationServiceInfo': [],
     'StopAllStationServices': [],
     'CleanUp': [],
     'SelectShipDlg': [],
     'GetServiceState': []}
    __dependencies__ = ['journal', 'insurance']
    __notifyevents__ = ['OnCharNowInStation',
     'OnCharNoLongerInStation',
     'OnStationOwnerChanged',
     'OnGodmaItemChange',
     'ProcessStationServiceItemChange',
     'ProcessSessionChange',
     'OnSetDevice']

    def Run(self, memStream = None):
        self.LogInfo('Starting Station Service')
        self.CleanUp()



    def ProcessSessionChange(self, isRemote, session, change):
        if ('stationid' in change):
            self.RemoveFullScreenSprite()
            (oldStationID, newStationID,) = change['stationid']
            if newStationID:
                self.GetServiceStates(1)
            else:
                self.serviceItemsState = None
            sm.GetService('michelle').RefreshCriminalFlagCountDown()



    def ProcessStationServiceItemChange(self, stationID, solarSystemID, serviceID, stationServiceItemID, isEnabled):
        self.GetServiceStates()
        if (serviceID in self.serviceItemsState):
            state = self.serviceItemsState[serviceID]
            state.stationServiceItemID = stationServiceItemID
            state.isEnabled = isEnabled
        sm.ScatterEvent('OnProcessStationServiceItemChange', stationID, solarSystemID, serviceID, stationServiceItemID, isEnabled)



    def GetServiceStates(self, force = 0):
        if ((not self.serviceItemsState) or force):
            if (util.IsOutpost(eve.session.stationid) or (sm.GetService('godma').GetType(eve.stationItem.stationTypeID).isPlayerOwnable == 1)):
                self.serviceItemsState = sm.RemoteSvc('corpStationMgr').GetStationServiceStates()
            else:
                self.serviceItemsState = {}



    def GetServiceState(self, serviceID):
        self.GetServiceStates()
        return self.serviceItemsState.get(serviceID, None)



    def OnSetDevice(self, *args):
        if (self.activeshipmodel is None):
            return 
        zoomTo = self.GetZoomValues(self.activeshipmodel, 1)
        camera = sm.GetService('sceneManager').GetRegisteredCamera('default')
        if (self.maxZoom < camera.translationFromParent.z):
            self.Zoom(zoomTo, None)



    def OnStationOwnerChanged(self, *args):
        uthread.pool('StationSvc::OnStationOwnerChanged --> LoadLobby', self.LoadLobby)



    def OnCharNowInStation(self, rec):
        (charID, corpID, allianceID, warFactionID,) = rec
        if (charID not in self.guests):
            self.guests[charID] = (corpID,
             allianceID,
             warFactionID)
        self.serviceItemsState = None



    def OnCharNoLongerInStation(self, rec):
        (charID, corpID, allianceID, factionID,) = rec
        if (charID in self.guests):
            self.guests.pop(charID)
        self.serviceItemsState = None



    def GetGuests(self):
        guests = sm.RemoteSvc('station').GetGuests()
        self.guests = {}
        for (charID, corpID, allianceID, warFactionID,) in guests:
            self.guests[charID] = (corpID,
             allianceID,
             warFactionID)

        return self.guests



    def IsGuest(self, whoID):
        return (whoID in self.guests)



    def Stop(self, memStream = None):
        self.LogInfo('Stopping Station Service')
        self.CleanUp()



    def CheckSession(self, change):
        if (self.activeShip != eve.session.shipid):
            if eve.session.shipid:
                hangarInv = eve.GetInventory(const.containerHangar)
                hangarItems = hangarInv.List()
                for each in hangarItems:
                    if (each.itemID == eve.session.shipid):
                        self.activeShipItem = each
                        self.ShowActiveShip()
                        break




    def GetStation(self):
        self.station = sm.GetService('ui').GetStation(eve.session.stationid)



    def GetStationServiceInfo(self, sortBy = None, stationInfo = None):
        if ((not self.station) and eve.session.stationid):
            self.GetStation()
        services = []
        for (service, info,) in self.GetStationServices().iteritems():
            sortby = info[0]
            if (sortBy == 'name'):
                sortby = info[2]
            services.append((sortby, (service,
              info[1],
              info[2],
              info[3],
              info[4],
              info[5])))

        services = uiutil.SortListOfTuples(services)
        return services



    def GetServiceDisplayName(self, service):
        s = self.GetStationServices(service)
        if s:
            return s[2]
        else:
            return mls.UI_GENERIC_UNKNOWN



    def GetStationServices(self, service = None):
        mapping = [['charcustomization',
          'OpenCharacterCustomization',
          mls.UI_CHARCREA_RECUSTOMIZATION,
          '66_03',
          True,
          (-1,)],
         ['medical',
          'OpenMedical',
          mls.UI_STATION_MEDICAL,
          '18_03',
          True,
          (const.stationServiceCloning,
           const.stationServiceSurgery,
           const.stationServiceDNATherapy)],
         ['repairshop',
          'OpenRepairshop',
          mls.UI_STATION_REPAIRSHOP,
          '18_04',
          True,
          (const.stationServiceRepairFacilities)],
         ['reprocessingPlant',
          'OpenReprocessingPlant',
          mls.UI_STATION_REPROCESSINGPLANT,
          '17_01',
          True,
          (const.stationServiceReprocessingPlant)],
         ['market',
          'OpenMarket',
          mls.UI_MARKET_MARKET,
          '18_01',
          False,
          (const.stationServiceMarket)],
         ['fitting',
          'OpenFitting',
          mls.UI_STATION_FITTING,
          '17_04',
          False,
          (const.stationServiceFitting)],
         ['factories',
          'OpenFactories',
          mls.UI_RMR_SCIENCEANDINDUSTRY,
          '57_09',
          False,
          (const.stationServiceFactory, const.stationServiceLaboratory)],
         ['missions',
          'OpenMissions',
          mls.UI_STATION_BOUNTY,
          '61_02',
          True,
          (const.stationServiceBountyMissions, const.stationServiceAssassinationMissions)],
         ['navyoffices',
          'OpenMilitia',
          mls.UI_STATION_MILITIAOFFICE,
          '61_03',
          False,
          (const.stationServiceNavyOffices)],
         ['insurance',
          'OpenInsurance',
          mls.UI_STATION_INSURANCE,
          '33_04',
          True,
          (const.stationServiceInsurance)],
         ['lpstore',
          'OpenLpstore',
          mls.UI_LPSTORE_LPSTORE,
          '70_11',
          True,
          (const.stationServiceLoyaltyPointStore)]]
        newmapping = {}
        for (i, servicemap,) in enumerate(mapping):
            (lbl, cmdstr, label, icon, stationonly, servicemasks,) = servicemap
            newmapping[lbl] = (i,
             cmdstr,
             label,
             icon,
             stationonly,
             servicemasks)

        if service:
            return newmapping.get(service, None)
        else:
            return newmapping



    def CheckHasStationService(self, service, serviceMask):
        return 



    def CleanUp(self, storeCamera = 1):
        try:
            if getattr(self, 'underlay', None):
                sm.GetService('window').UnregisterWindow(self.underlay)
                self.underlay.OnClick = None
                self.underlay.Minimize = None
                self.underlay.Maximize = None
        except:
            pass
        uix.Close(self, ['closeBtn',
         'hint',
         'underlay',
         'lobby'])
        self.lobby = None
        self.underlay = None
        self.closeBtn = None
        self.hint = None
        self.fittingflags = None
        self.selected_service = None
        self.loading = None
        self.active_service = None
        self.activeShip = None
        self.activeShipItem = None
        self.activeshipmodel = None
        self.refreshingfitting = 0
        self.loadingSvc = 0
        self.dockaborted = 0
        self.exitingstation = 0
        self.activatingShip = 0
        self.leavingShip = 0
        self.guests = {}
        self.serviceItemsState = {}
        self.maxZoom = -150.0
        self.minZoom = -750.0
        self.station = None
        self.previewColorIDs = {'MAIN': 0,
         'MARKINGS': 0,
         'LIGHTS': 0}
        layer = uicore.layer.station
        if layer:
            uix.Flush(layer)



    def StopAllStationServices(self):
        services = self.GetStationServiceInfo()
        for service in services:
            if sm.IsServiceRunning(service[0]):
                sm.services[service[0]].Stop()




    def Setup(self, reloading = 0):
        self.CleanUp(0)
        self.loading = 1
        if not reloading:
            eve.Message('OnEnterStation')
        stationTypeID = eve.stationItem.stationTypeID
        stationType = cfg.invtypes.Get(stationTypeID)
        stationRace = stationType['raceID']
        if not util.IncarnaNPEEnabled():
            if (stationRace == 1):
                scenePath = 'res:/dx9/scene/hangar/caldari.red'
            elif (stationRace == 2):
                scenePath = 'res:/dx9/scene/hangar/minmatar.red'
            elif (stationRace == 4):
                scenePath = 'res:/dx9/scene/hangar/amarr.red'
            elif (stationRace == 8):
                scenePath = 'res:/dx9/scene/hangar/gallente.red'
            else:
                scenePath = 'res:/dx9/scene/hangar/gallente.red'
            sm.GetService('sceneManager').UnregisterScene('default')
            sm.GetService('sceneManager').UnregisterScene2('default')
            sm.GetService('sceneManager').UnregisterCamera('default')
            sm.GetService('sceneManager').LoadScene(scenePath, scenePath, registerKey='default')
            camera = sm.GetService('sceneManager').GetRegisteredCamera('default')
            scene2 = sm.StartService('sceneManager').GetRegisteredScene2('default')
            stationModel = scene2.objects[0]
            stationModel.enableShadow = False
            for each in camera.zoomCurve.keys:
                each.value = 1.0

            camera.fieldOfView = 1.0
            camera.frontClip = 10.0
            camera.minPitch = 0.0
        if not util.IncarnaNPEEnabled():
            if eve.session.shipid:
                self.ShowShip(eve.session.shipid)
                camera.OrbitParent(-8.0, -4.0)
            else:
                self.CheckScene()
            if (self.activeshipmodel is not None):
                sceneScaling = 2.0
                if (self.activeshipmodel and (self.activeshipmodel.boundingSphereRadius > 1500.0)):
                    sceneScaling *= (self.activeshipmodel.boundingSphereRadius / 1500.0)
                scene2.objects[0].modelScale = sceneScaling
                scene2.fogEnd *= sceneScaling
                scene2.fogStart *= sceneScaling
        if not (eve.rookieState and (eve.rookieState < 5)):
            self.LoadLobby()
        if ((self.station is None) and eve.session.stationid):
            self.station = sm.GetService('ui').GetStation(eve.session.stationid)
        sm.GetService('autoPilot').SetOff('toggled by Station Entry')
        mapSvc = sm.StartService('map')
        if mapSvc.IsOpen():
            mapSvc.MinimizeWindows()
        planetUISvc = sm.GetService('planetUI')
        if planetUISvc.IsOpen():
            planetUISvc.MinimizeWindows()
        if ((not util.IncarnaNPEEnabled()) and (not (mapSvc.IsOpen() or planetUISvc.IsOpen()))):
            uix.GetStationNav()
        self.loading = 0
        self.sprite = None
        if not reloading:
            if (eve.session.shipid == None):
                sm.GetService('tutorial').OpenTutorialSequence_Check(uix.cloningWhenPoddedTutorial)
            if (sm.GetService('skills').GetSkillPoints() >= 1500000):
                sm.GetService('tutorial').OpenTutorialSequence_Check(uix.cloningTutorial)
            sm.GetService('loading').FadeFromBlack()



    def StopAllBlinkButtons(self):
        lobby = self.GetLobby()
        if not lobby:
            return 
        for each in uiutil.GetChild(lobby, 'btnparent').children:
            if hasattr(each, 'Blink'):
                each.Blink(0)




    def BlinkButton(self, what):
        lobby = self.GetLobby()
        if not lobby:
            return 
        for each in uiutil.GetChild(lobby, 'btnparent').children:
            if (each.name.lower() == what.lower()):
                each.Blink(blinks=40)




    def RenderStaticEnvironment(self):
        if ((not eve.session.stationid) or (settings.user.ui.Get('loadstationenv', 1) or (sm.GetService('map').IsOpen() or sm.GetService('planetUI').IsOpen()))):
            return 
        trinity.WaitForResourceLoads()
        dev = trinity.GetDevice()
        camera = sm.GetService('sceneManager').GetRegisteredCamera('default')
        s1 = sm.GetService('sceneManager').GetRegisteredScene('default')
        s2 = sm.GetService('sceneManager').GetRegisteredScene2('default')
        s2.display = True
        clientWidth = trinity.GetDevice().width
        clientHeight = trinity.GetDevice().height
        target = trinity.TriSurfaceManaged(dev.CreateRenderTarget, clientWidth, clientHeight, trinity.TRIFMT_X8R8G8B8, trinity.TRIMULTISAMPLE_NONE, 0, 1)
        stencil = trinity.TriSurfaceManaged(dev.CreateDepthStencilSurface, clientWidth, clientHeight, trinity.TRIFMT_D24S8, trinity.TRIMULTISAMPLE_NONE, 0, 1)
        rgbSource = trinity.TriSurfaceManaged(dev.CreateOffscreenPlainSurface, clientWidth, clientHeight, trinity.TRIFMT_X8R8G8B8, trinity.TRIPOOL_SYSTEMMEM)
        updateJob = trinity.CreateRenderJob('UpdateScene')
        updateJob.Update(s1)
        updateJob.Update(s2)
        updateJob.ScheduleOnce()
        updateJob.WaitForFinish()
        eye = camera.pos
        at = camera.intr
        view = trinity.TriView()
        view.SetLookAtPosition((eye.x,
         eye.y,
         eye.z), (at.x,
         at.y,
         at.z), (0.0, 1.0, 0.0))
        projection = trinity.TriProjection()
        fov = camera.fieldOfView
        aspectRatio = (float(clientWidth) / clientHeight)
        projection.PerspectiveFov(fov, aspectRatio, 1.0, 350000.0)
        renderJob = trinity.CreateRenderJob('StaticScene')
        renderJob.SetRenderTarget(target)
        renderJob.SetProjection(projection)
        renderJob.SetView(view)
        renderJob.SetDepthStencil(stencil)
        renderJob.Clear((0.0, 0.0, 0.0, 0.0), 1.0)
        renderJob.RenderScene(s2)
        renderJob.ScheduleOnce()
        renderJob.WaitForFinish()
        dev.GetRenderTargetData(target, rgbSource)
        self.RemoveFullScreenSprite()
        self.sprite = uicls.Sprite(parent=eve.triapp.uilib.desktop, width=trinity.GetDevice().width, height=trinity.GetDevice().height, left=0, top=0)
        self.sprite.name = 'fullScreenSprite'
        self.sprite.texture.AttachSurface(rgbSource)
        self.sprite.Invalidate()



    def RemoveFullScreenSprite(self):
        for each in eve.triapp.uilib.desktop.children:
            if (each.name == 'fullScreenSprite'):
                eve.triapp.uilib.desktop.children.fremove(each)




    def CheckScene(self):
        scene = sm.GetService('sceneManager').GetRegisteredScene2('default')
        if not settings.user.ui.Get('loadstationenv', 1):
            self.RenderStaticEnvironment()
            scene.display = False
        else:
            scene.display = True
            self.RemoveFullScreenSprite()
        if (sm.GetService('sceneManager').GetActiveScene1() == scene):
            uix.GetStationNav()



    def StopSceneUpdate(self):
        eve.WaitForResourceLoad()
        scene = sm.GetService('sceneManager').GetRegisteredScene('default')
        scene.update = 0



    def DoPrepare(self):
        uthread.new(self.CheckScene)



    def LoadLobby(self):
        if not eve.session.stationid:
            return 
        self.GetLobby(1, 1)



    def DoPOSWarning(self):
        if (sm.GetService('godma').GetType(eve.stationItem.stationTypeID).isPlayerOwnable == 1):
            eve.Message('POStationWarning')



    def GetActiveShip(self):
        return eve.session.shipid



    def TryActivateShip(self, invitem, onSessionChanged = 0, secondTry = 0):
        shipid = invitem.itemID
        if (shipid == self.activeShip):
            return 
        if self.activatingShip:
            return 
        techLevel = sm.StartService('godma').GetTypeAttribute(invitem.typeID, const.attributeTechLevel)
        if (((techLevel is not None) and (int(techLevel) == 3)) and (eve.Message('AskActivateTech3Ship', {}, uix.YESNO, suppress=uix.ID_YES) != uix.ID_YES)):
            return 
        self.activatingShip = 1
        try:
            try:
                shipsvc = sm.GetService('gameui').GetShipAccess()
                if (eve.session.shipid != shipid):
                    sm.GetService('gameui').KillCargoView(eve.session.shipid)
                    sm.GetService('sessionMgr').PerformSessionChange('board', shipsvc.Board, shipid, (session.shipid or session.stationid), violateSafetyTimer=onSessionChanged)
            except UserError, what:
                if (self.activeShipItem and (not secondTry)):
                    self.TryActivateShip(self.activeShipItem, secondTry=1)
                if (what.args[0] == 'CallGroupLocked'):
                    sys.exc_clear()
                    eve.Message('Busy')
                    return 
                if (what.args[0] == 'TooFewSubSystemsToUndock'):
                    groupIDs = what.args[1]
                    slimItem = sm.StartService('godma').GetItem(shipid)
                    sm.services['window'].GetWindow('AssembleShip', create=1, decoClass=form.AssembleShip, ship=invitem, groupIDs=groupIDs)
                    return 
                raise 
            except RuntimeError, what:
                if (self.activeShipItem and (not secondTry)):
                    self.TryActivateShip(self.activeShipItem, secondTry=1)
                if (what.args[0] == 'RequiredParameterException'):
                    sys.exc_clear()
                    eve.Message('Busy')
                    return 
                raise 
            self.activeShipItem = invitem
            self.ShowActiveShip()
            if (invitem.groupID != const.groupRookieship):
                sm.GetService('tutorial').OpenTutorialSequence_Check(uix.insuranceTutorial)

        finally:
            self.activatingShip = 0




    def TryLeaveShip(self, invitem, onSessionChanged = 0, secondTry = 0):
        shipid = invitem.itemID
        if ((not util.IncarnaNPEEnabled()) and (shipid != self.activeShip)):
            return 
        if self.leavingShip:
            return 
        self.leavingShip = 1
        try:
            try:
                shipsvc = sm.GetService('gameui').GetShipAccess()
                sm.GetService('gameui').KillCargoView(shipid)
                capsuleID = sm.GetService('sessionMgr').PerformSessionChange('leaveship', shipsvc.LeaveShip, violateSafetyTimer=onSessionChanged)
                self.ShowShip(capsuleID)
            except UserError, what:
                if (self.activeShipItem and (not secondTry)):
                    self.TryLeaveShip(self.activeShipItem, secondTry=1)
                if (what.args[0] == 'CallGroupLocked'):
                    sys.exc_clear()
                    eve.Message('Busy')
                    return 
                raise 
            except RuntimeError, what:
                if (self.activeShipItem and (not secondTry)):
                    self.TryLeaveShip(self.activeShipItem, secondTry=1)
                if (what.args[0] == 'RequiredParameterException'):
                    sys.exc_clear()
                    eve.Message('Busy')
                    return 
                raise 

        finally:
            self.leavingShip = 0




    def ShowShip(self, shipID):
        self.WaitForShip(shipID)
        hangarInv = eve.GetInventory(const.containerHangar)
        hangarItems = hangarInv.List()
        for each in hangarItems:
            if (each.itemID == shipID):
                self.activeShipItem = each
                try:
                    self.ShowActiveShip()
                except Exception, e:
                    log.LogException('Failed to show ship')
                    sys.exc_clear()
                break




    def GetTech3ShipFromSlimItem(self, slimItem):
        subSystemIds = {}
        for module in slimItem.modules:
            if (module.categoryID == const.categorySubSystem):
                subSystemIds[module.groupID] = module.typeID

        if (len(subSystemIds) < const.visibleSubSystems):
            sm.services['window'].GetWindow('AssembleShip', create=1, decoClass=form.AssembleShip, ship=slimItem, groupIDs=subSystemIds.keys())
            return 
        else:
            return sm.StartService('t3ShipSvc').GetTech3ShipFromDict(slimItem.typeID, subSystemIds)



    def ShowActiveShip(self, thread = 1):
        if getattr(self, '__alreadyShowingActiveShip', False):
            return 
        setattr(self, '__alreadyShowingActiveShip', True)
        scene = sm.GetService('sceneManager').GetRegisteredScene('default')
        if (scene is None):
            return 
        scene.update = 1
        invitem = self.activeShipItem
        for each in scene.models[:]:
            if (each.name == str(self.activeShip)):
                scene.models.remove(each)

        scene2 = sm.StartService('sceneManager').GetRegisteredScene2('default')
        if scene2:
            for each in scene2.objects:
                if (getattr(each, 'name', None) == str(self.activeShip)):
                    scene2.objects.remove(each)

        blueObject = None
        try:
            techLevel = sm.GetService('godma').GetTypeAttribute(invitem.typeID, const.attributeTechLevel)
            if (techLevel == 3.0):
                try:
                    slimItem = sm.GetService('godma').GetItem(self.activeShipItem.itemID)
                    newModel = self.GetTech3ShipFromSlimItem(slimItem)
                except:
                    log.LogException('failed bulding modular ship')
                    sys.exc_clear()
                    return 
            else:
                modelPath = cfg.invtypes.Get(invitem.typeID).GraphicFile()
                newFilename = modelPath.lower().replace(':/model', ':/dx9/model')
                newFilename = newFilename.replace('.blue', '.red')
                newModel = trinity.Load(newFilename)
        except Exception, e:
            log.LogException(str(e))
            sys.exc_clear()
        newModel.FreezeHighDetailMesh()
        zoomTo = self.GetZoomValues(newModel, thread)
        if hasattr(newModel, 'ChainAnimationEx'):
            newModel.ChainAnimationEx('NormalLoop', 0, 0, 1.0)
        self.activeShip = invitem.itemID
        self.activeshipmodel = newModel
        self.FitHardpoints(0)
        newModel.display = 1
        newModel.name = str(invitem.itemID)
        scene2.objects.append(newModel)
        sm.ScatterEvent('OnActiveShipModelChange', newModel)
        self.Zoom(zoomTo, thread=thread)
        delattr(self, '__alreadyShowingActiveShip')



    def GetActiveShipModel(self):
        return self.activeshipmodel



    def GetZoomValues(self, model, thread):
        rad = 300
        camera = sm.GetService('sceneManager').GetRegisteredCamera('default')
        trinity.WaitForResourceLoads()
        rad = model.GetBoundingSphereRadius()
        center = model.boundingSphereCenter
        localBB = model.GetLocalBoundingBox()
        if ((localBB[0] is None) or (localBB[1] is None)):
            log.LogError("Failed to get bounding info for ship. Odds are the ship wasn't loaded properly.")
            localBB = (trinity.TriVector(0, 0, 0), trinity.TriVector(0, 0, 0))
        model.translationCurve = trinity.TriVectorCurve()
        import types
        if (type(center) == types.TupleType):
            negativeCenter = (-center[0],
             -center[1],
             -center[2])
            model.translationCurve.value = trinity.TriVector(*negativeCenter)
        else:
            negativeCenter = -center
            model.translationCurve.value = negativeCenter
        model.translationCurve.value.y = (-localBB[0].y + 180.0)
        model.modelRotationCurve = blue.os.LoadObject('res:/dx9/model/shared/ship_modelRotationCurve.blue')
        model.modelTranslationCurve = blue.os.LoadObject('res:/dx9/model/shared/ship_modelTranslationCurve.blue')
        cameraparent = self.GetCameraParent()
        cameraparent.translation.y = (-localBB[0].y + 180.0)
        zoomMultiplier = 1.0
        aspectRatio = trinity.GetAspectRatio()
        if (aspectRatio > 1.6):
            zoomMultiplier = (aspectRatio / 1.6)
        self.maxZoom = (-((rad + camera.frontClip) + 50) * zoomMultiplier)
        self.minZoom = -2050.0
        return (-(rad + camera.frontClip) * 2)



    def GetCameraParent(self):
        scene = sm.GetService('sceneManager').GetRegisteredScene('default')
        for each in scene.models:
            if (each.name == 'cameraparent'):
                return each

        cp = trinity.TriTransform()
        cp.name = 'cameraparent'
        scene.models.append(cp)
        return cp



    def FindHierarchicalBoundingBox(self, transform, printout, indent = '', minx = 1e+100, maxx = -1e+100, miny = 1e+100, maxy = -1e+100, minz = 1e+100, maxz = -1e+100):
        transform.Update(blue.os.GetTime())
        if printout:
            print indent,
            print transform.name
        if (hasattr(transform, 'translation') and (transform.__typename__ in ('TriTransform', 'TriSplTransform', 'TriLODGroup'))):
            if ((transform.__typename__ == 'TriTransform') and (transform.transformBase != trinity.TRITB_OBJECT)):
                return (minx,
                 maxx,
                 miny,
                 maxy,
                 minz,
                 maxz)
            if (hasattr(transform, 'object') and (transform.object is not None)):
                doMesh = False
                if (getattr(transform.object, 'vertexRes', None) is not None):
                    v = transform.object.vertexRes
                    meshBoxMin = v.meshBoxMin.CopyTo()
                    meshBoxMax = v.meshBoxMax.CopyTo()
                    doMesh = True
                elif (transform.object.__typename__ in ('TriMesh', 'TriMultiMesh')):
                    meshBoxMin = transform.object.meshBoxMin.CopyTo()
                    meshBoxMax = transform.object.meshBoxMax.CopyTo()
                    doMesh = True
                if doMesh:
                    meshBoxMin.TransformCoord(transform.worldTransform)
                    meshBoxMax.TransformCoord(transform.worldTransform)
                    minx = min(minx, meshBoxMin.x)
                    maxx = max(maxx, meshBoxMax.x)
                    miny = min(miny, meshBoxMin.y)
                    maxy = max(maxy, meshBoxMax.y)
                    minz = min(minz, meshBoxMin.z)
                    maxz = max(maxz, meshBoxMax.z)
            for child in transform.children:
                indent = (indent + '  ')
                (minx, maxx, miny, maxy, minz, maxz,) = self.FindHierarchicalBoundingBox(child, printout, indent, minx, maxx, miny, maxy, minz, maxz)

        return (minx,
         maxx,
         miny,
         maxy,
         minz,
         maxz)



    def OnGodmaItemChange(self, item, change):
        if (session.stationid is None):
            return 
        if (item.groupID in (const.groupFrequencyMiningLaser,
         const.groupStripMiner,
         const.groupEnergyWeapon,
         const.groupProjectileWeapon,
         const.groupHybridWeapon,
         const.groupMiningLaser,
         const.groupGasCloudHarvester)):
            self.FitHardpoints()
        if ((item.locationID == change.get(const.ixLocationID, None)) and (item.flagID == change.get(const.ixFlag))):
            return 
        if ((item.locationID == session.shipid) and (cfg.IsShipFittingFlag(item.flagID) and (item.categoryID == const.categorySubSystem))):
            sm.GetService('station').ShowShip(eve.session.shipid)



    def ModuleListFromGodmaSlimItem(self, slimItem):
        list = []
        for module in slimItem.modules:
            list.append((module.itemID, module.typeID))

        list.sort()
        return list



    def FitHardpoints(self, checkScene = 1):
        if ((not self.activeshipmodel) or self.refreshingfitting):
            return 
        self.refreshingfitting = 1
        scene = sm.GetService('sceneManager').GetRegisteredScene('default')
        scene.update = 1
        if turret.TurretSet.Winter2010TurretsEnabled_ToBeRemoved():
            turret.TurretSet.FitTurrets(eve.session.shipid, self.activeshipmodel)
        elif (getattr(self.activeshipmodel, '__bluetype__', '') == 'trinity.EveShip2'):
            self.FitHardpoints2(self.activeshipmodel)
        elif (getattr(self.activeshipmodel, '__bluetype__', '') == 'eve.EveShip'):
            self.FitHardpoints_DX9(self.activeshipmodel)
        else:
            self.FitHardpoints_DX8(self.activeshipmodel)
        self.refreshingfitting = 0
        if checkScene:
            self.CheckScene()



    def FitHardpoints2(self, shipModel):
        shipid = eve.session.shipid
        del shipModel.turrets[:]
        slimItem = sm.GetService('godma').GetItem(shipid)
        modules = self.ModuleListFromGodmaSlimItem(slimItem)
        if (slimItem is None):
            self.LogError('no invitem property for ship')
            return 
        slotcounter = 0
        for (moduleID, typeID,) in modules:
            to = cfg.invtypes.Get(typeID)
            groupID = to.groupID
            t = blue.os.GetTime(-1)
            if ((groupID == const.groupStripMiner) or ((typeID == 17912) or (typeID == 24305))):
                turretPair = turret.Turret_sc2()
                eveTurretPair = turretPair.Initialize('aim111', (('locator_turret_' + str((slotcounter + 1))) + 'a'), (('locator_turret_' + str((slotcounter + 1))) + 'b'), 5000)
                shipModel.turrets.append(eveTurretPair)
                slotcounter += 1
            elif (groupID == const.groupGasCloudHarvester):
                turretPair = turret.Turret_sc2()
                eveTurretPair = turretPair.Initialize('gasminersmall', (('locator_turret_' + str((slotcounter + 1))) + 'a'), (('locator_turret_' + str((slotcounter + 1))) + 'b'))
                shipModel.turrets.append(eveTurretPair)
                slotcounter += 1
            else:
                if ((groupID in [const.groupEnergyWeapon,
                 const.groupProjectileWeapon,
                 const.groupHybridWeapon,
                 const.groupMiningLaser]) or (typeID == 18068)):
                    turretPair = turret.Turret_sc2()
                    if ((groupID == const.groupMiningLaser) or (typeID == 18068)):
                        eveTurretPair = turretPair.Initialize(to.GraphicFile(), (('locator_turret_' + str((slotcounter + 1))) + 'a'), (('locator_turret_' + str((slotcounter + 1))) + 'b'), 2500)
                    else:
                        eveTurretPair = turretPair.Initialize(to.GraphicFile(), (('locator_turret_' + str((slotcounter + 1))) + 'a'), (('locator_turret_' + str((slotcounter + 1))) + 'b'))
                    shipModel.turrets.append(eveTurretPair)
                    slotcounter += 1

        shipModel.RebuildCachedLocatorIndices()



    def FitHardpoints_DX8(self, shipmodel):
        try:
            shipid = eve.session.shipid
            turret.HackLocators(shipmodel)
            turretList = uiutil.SortByAttribute(nodemanager.FindNodes(shipmodel, 'locator_turret', 'trinity.TriSplTransform'))
            for each in turretList:
                del each.children[:]

            ship = sm.GetService('godma').GetItem(shipid)
            slotcounter = 0
            for module in ship.modules:
                if (len(turretList) < ((slotcounter * 2) + 1)):
                    continue
                if ((module.groupID == const.groupStripMiner) or ((module.typeID == 17912) or (module.typeID == 24305))):
                    turretPair = turret.StripMiningTurretPair()
                    turretPair.Initialize(module.graphicID, 5000)
                    hardpoint0 = turretList[(slotcounter * 2)]
                    hardpoint1 = turretList[((slotcounter * 2) + 1)]
                    hardpoint0.children.append(turretPair.turret1.model)
                    hardpoint1.children.append(turretPair.turret2.model)
                    stretchSourceList = nodemanager.FindNodes(turretPair.turret1.model, 'source_placement', 'trinity.TriStretch')
                    stretchSourceList.extend(nodemanager.FindNodes(turretPair.turret2.model, 'source_placement', 'trinity.TriStretch'))
                    for tf in stretchSourceList:
                        for tfChild in tf.children:
                            tfChild.scaling.Scale(0.25)


                elif (module.groupID == const.groupGasCloudHarvester):
                    harvesterPair = gasHarvester.GasHarvesterPair()
                    harvesterPair.Initialize(cfg.invtypes.Get(module.typeID).GraphicFile())
                    hardpoint0 = turretList[(slotcounter * 2)]
                    hardpoint1 = turretList[((slotcounter * 2) + 1)]
                    hardpoint0.children.append(harvesterPair.harvester1.model)
                    hardpoint1.children.append(harvesterPair.harvester2.model)
                elif ((module.groupID in [const.groupEnergyWeapon,
                 const.groupProjectileWeapon,
                 const.groupHybridWeapon,
                 const.groupMiningLaser]) or (module.typeID == 18068)):
                    turretPair = None
                    if ((module.groupID == const.groupMiningLaser) or (module.typeID == 18068)):
                        turretPair = turret.MiningTurretPair()
                        turretPair.Initialize(module.graphicID, 2500)
                    else:
                        turretPair = turret.TurretPair()
                        turretPair.Initialize(module.graphicID)
                    hardpoint1 = turretList[(slotcounter * 2)]
                    hardpoint2 = turretList[((slotcounter * 2) + 1)]
                    hardpoint1.object = turretPair.turrets[0].triTurret
                    hardpoint2.object = turretPair.turrets[1].triTurret
                    turretPair.turrets[0].owner = hardpoint1
                    turretPair.turrets[1].owner = hardpoint2
                    for aTurret in turretPair.turrets:
                        if (module.groupID == const.groupEnergyWeapon):
                            aTurret.guntype = 'e'
                        else:
                            aTurret.guntype = 'p'
                        aTurret.AddLight()

                else:
                    continue
                slotcounter += 1


        finally:
            self.refreshingfitting = 0




    def FitHardpoints_DX9(self, shipModel):
        shipid = eve.session.shipid
        while len(shipModel.turrets):
            del shipModel.turrets[0]

        while len(shipModel.attachments):
            del shipModel.attachments[0]

        turretList = nodemanager.FindNodes(shipModel.locators, 'locator_turret', 'trinity.TriTransform')
        turretList.sort(lambda a, b: cmp(a.name, b.name))
        turretLocatorPairs = []
        for i in xrange((len(turretList) / 2)):
            turretLocatorPairs.append((turretList[(2 * i)], turretList[((2 * i) + 1)]))

        slimItem = sm.GetService('godma').GetItem(shipid)
        if (slimItem is None):
            log.general.Log(('no invitem property for ship no ' + str(self.id)), log.LGERR)
            return 
        slotcounter = 0
        for module in slimItem.modules:
            moduleID = module.itemID
            typeID = module.typeID
            groupID = module.groupID
            graphicID = module.graphicID
            log.general.Log(('fitting module %s type %s' % (moduleID, typeID)))
            t = blue.os.GetTime(-1)
            if ((groupID == const.groupStripMiner) or ((typeID == 17912) or (typeID == 24305))):
                turretPair = turret.NewTurret()
                eveTurretPair = turretPair.Initialize('aim111', (('locator_turret_' + str((slotcounter + 1))) + 'a'), (('locator_turret_' + str((slotcounter + 1))) + 'b'))
                shipModel.turrets.append(eveTurretPair)
                slotcounter += 1
            elif (groupID == const.groupGasCloudHarvester):
                harvesterPair = gasHarvester.GasHarvesterPair()
                harvesterPair.Initialize(cfg.invtypes.Get(typeID).GraphicFile())
                hardpoint1 = trinity.EveAttachment()
                hardpoint2 = trinity.EveAttachment()
                hardpoint1.object = harvesterPair.harvester1.model
                hardpoint1.locatorName = (('locator_turret_' + str((slotcounter + 1))) + 'a')
                hardpoint2.object = harvesterPair.harvester2.model
                hardpoint2.locatorName = (('locator_turret_' + str((slotcounter + 1))) + 'b')
                shipModel.attachments.append(hardpoint1)
                shipModel.attachments.append(hardpoint2)
                slotcounter += 1
            else:
                if ((groupID in [const.groupEnergyWeapon,
                 const.groupProjectileWeapon,
                 const.groupHybridWeapon,
                 const.groupMiningLaser]) or (typeID == 18068)):
                    turretPair = turret.NewTurret()
                    eveTurretPair = turretPair.Initialize(util.GraphicFile(graphicID), (('locator_turret_' + str((slotcounter + 1))) + 'a'), (('locator_turret_' + str((slotcounter + 1))) + 'b'))
                    shipModel.turrets.append(eveTurretPair)
                    slotcounter += 1

        shipModel.RebuildCachedLocatorIndices()



    def CheckCameraTranslation(self, trans):
        return min(self.maxZoom, max(trans, self.minZoom))



    def Zoom(self, zoomto = None, thread = 1, ignoreCloser = False):
        cameraparent = self.GetCameraParent()
        scene = sm.GetService('sceneManager').GetRegisteredScene('default')
        camera = sm.GetService('sceneManager').GetRegisteredCamera('default')
        camera.parent = cameraparent
        currd = camera.translationFromParent.z
        endd = self.CheckCameraTranslation(zoomto)
        if (ignoreCloser and (endd > currd)):
            return 
        scene.update = 1
        scene.display = 1
        if thread:
            t = uthread.new(self.Zoom_thread, currd, endd)
            t.context = 'station::Zoom'
        else:
            camera.translationFromParent.z = endd
            self.CheckScene()



    def Zoom_thread(self, currd, endd):
        start = blue.os.GetTime()
        ndt = 0.0
        camera = sm.GetService('sceneManager').GetRegisteredCamera('default')
        while (ndt != 1.0):
            ndt = min((blue.os.TimeDiffInMs(start) / 250.0), 1.0)
            camera.translationFromParent.z = mathUtil.Lerp(currd, endd, ndt)
            blue.pyos.synchro.Yield()

        self.CheckScene()



    def GetUnderlay(self):
        if (self.underlay is None):
            for each in uicore.layer.main.children[:]:
                if ((each is not None) and ((not each.destroyed) and (each.name == 'services'))):
                    sm.GetService('window').UnregisterWindow(each)
                    each.OnClick = None
                    each.Minimize = None
                    each.Maximize = None
                    each.Close()

            self.underlay = uicls.Sprite(uicls.Container(name='services', parent=uicore.layer.main, align=uiconst.TOTOP, state=uiconst.UI_HIDDEN))
            self.underlay.scope = 'station'
            self.underlay.minimized = 0
            self.underlay.Minimize = self.MinimizeUnderlay
            self.underlay.Maximize = self.MaximizeUnderlay
            main = uicls.Container(name='mainparentXX', parent=self.underlay, align=uiconst.TOALL, pos=(0, 0, 0, 0))
            main.OnClick = self.ClickParent
            main.state = uix.UI_NORMAL
            sub = uicls.Container(name='subparent', parent=main, align=uiconst.TOALL, pos=(0, 0, 0, 0))
            captionparent = uicls.Container(name='captionparent', parent=main, align=uiconst.TOPLEFT, left=128, top=36, idx=0)
            caption = uix.GetCaption('', captionparent)
            self.closeBtn = uix.MakeBtnGroup([[mls.UI_CMD_CLOSE,
              self.CloseSvc,
              None,
              81]], where=sub)
            underlay = uix.GetUnderlay(main, left=-1, top=-10)
            uicls.Container(name='push', parent=underlay, idx=0, align=uiconst.TOBOTTOM, height=10)
            svcparent = uicls.Container(name='serviceparent', parent=sub, align=uiconst.TOALL, pos=(0, 0, 0, 0))
            self.underlay.sr.main = main
            self.underlay.sr.svcparent = svcparent
            self.underlay.sr.caption = caption
            sm.GetService('window').RegisterWindow(self.underlay)
        return self.underlay



    def MinimizeUnderlay(self, *args):
        self.underlay.state = uix.UI_HIDDEN



    def MaximizeUnderlay(self, *args):
        self.underlay.state = uix.UI_PICKCHILDREN
        self.ClickParent()



    def ClickParent(self, *args):
        for each in uicore.layer.main.children:
            if ((getattr(each, 'isDockWnd', 0) == 1) and (each.state == uix.UI_NORMAL)):
                uiutil.SetOrder(each, -1)




    def LoadSvc(self, service, close = 1):
        serviceInfo = self.GetStationServices(service)
        if ((service is not None) and (serviceInfo is not None)):
            (pos, cmdstr, label, icon, stationonly, servicemasks,) = serviceInfo
            self.ExecuteCommand(cmdstr)
            return 
        if getattr(self, 'loadingSvc', 0):
            return 
        self.loadingSvc = 1
        while self.loading:
            blue.pyos.synchro.Sleep(500)

        if (self.selected_service is None):
            if service:
                self._LoadSvc(1, service)
        elif (service == self.selected_service):
            if close:
                self._LoadSvc(0)
        else:
            self._LoadSvc(0, service)
        self.loadingSvc = 0



    def ExecuteCommand(self, cmdstr):
        func = getattr(uicore.cmd, cmdstr, None)
        if func:
            func()



    def GetSvc(self, svcname = None):
        if (self.active_service is not None):
            if (svcname is not None):
                if (self.selected_service == svcname):
                    return self.active_service
            else:
                return self.active_service



    def GetLobby(self, create = 0, doReload = 0):
        wnd = sm.GetService('window').GetWindow('lobby')
        if (wnd and (not wnd.destroyed)):
            if doReload:
                wnd.SelfDestruct()
            else:
                return wnd
        wnd = sm.GetService('window').GetWindow('lobby', create=create, decoClass=form.Lobby)
        return wnd



    def _LoadSvc(self, inout, service = None):
        self.loading = 1
        print '_LoadSvc',
        print service
        wnd = self.GetUnderlay()
        newsvc = None
        if ((inout == 1) and (wnd is not None)):
            self.ClearHint()
            (newsvc, svctype,) = self.SetupService(wnd, service)
        if (((wnd.absoluteRight - wnd.absoluteLeft) < 700) and (inout == 1)):
            sm.GetService('neocom').Minimize()
        height = (eve.triapp.uilib.desktop.height - 180)
        wnd.state = uix.UI_PICKCHILDREN
        if (inout == 1):
            sm.GetService('neocom').SetLocationInfoState(0)
        wnd.height = height
        if inout:
            wnd.top = -height
        uicore.effect.MorphUI(wnd, 'top', [-height, 0][inout], 500.0, 1, 1)
        snd = service
        if (inout == 0):
            snd = self.selected_service
        if (snd is not None):
            eve.Message(('LoadSvc_%s%s' % (snd, ['Out', 'In'][inout])))
        blue.pyos.synchro.Sleep([750, 1250][inout])
        if (inout == 0):
            sm.GetService('neocom').SetLocationInfoState(1)
        if (newsvc is not None):
            if (svctype == 'form'):
                print 'Start service'
                newsvc.Startup(self)
            elif settings.user.ui.Get('nottry', 0):
                newsvc.Initialize(wnd.sr.svcparent)
            else:
                try:
                    newsvc.Initialize(wnd.sr.svcparent)
                except:
                    log.LogException(channel=self.__guid__)
                    sys.exc_clear()
            self.active_service = newsvc
            self.selected_service = service
        else:
            uix.Flush(wnd.sr.svcparent)
            if (self.active_service and hasattr(self.active_service, 'Reset')):
                self.active_service.Reset()
            self.active_service = None
            self.selected_service = service
        self.loading = 0
        if ((inout == 0) and (service is not None)):
            self._LoadSvc(1, service)
        if ((inout == 0) and (service is None)):
            uix.Flush(wnd.sr.svcparent)



    def Startup(self, svc):
        uthread.new(svc.Startup, self)



    def GiveHint(self, hintstr, left = 80, top = 320, width = 300):
        self.ClearHint()
        if (self.hint is None):
            par = uicls.Container(name='captionParent', parent=self.GetUnderlay().sr.main, align=uiconst.TOPLEFT, top=top, left=left, width=width, height=256, idx=0)
            self.hint = uix.GetCaption('', par, align=uix.UI_ALCLIENT, left=0, top=0)
        self.hint.parent.top = top
        self.hint.parent.left = left
        self.hint.parent.width = width
        self.hint.text = (hintstr or '')



    def ClearHint(self):
        if (self.hint is not None):
            self.hint.text = ''



    def SetupService(self, wnd, servicename):
        uix.Flush(wnd.sr.svcparent)
        svc = None
        topheight = 128
        btmheight = 0
        icon = 'ui_09_64_14'
        sz = 128
        top = -16
        icon = uicls.Icon(icon=icon, parent=wnd.sr.svcparent, left=0, top=top, size=sz, idx=0)
        iconpar = uicls.Container(name='iconpar', parent=wnd.sr.svcparent, align=uiconst.TOTOP, height=96, clipChildren=1, state=uix.UI_PICKCHILDREN)
        bigicon = icon.CopyTo()
        bigicon.width = bigicon.height = (sz * 2)
        bigicon.top = -64
        bigicon.color.a = 0.1
        iconpar.children.append(bigicon)
        closeX = uicls.Sprite(blue.os.LoadObject('res:/UI/Component/closex.blue'))
        closeX.align = uix.UI_ALNONE
        closeX.left = closeX.top = 2
        closeX.anchors = uix.UI_ANCHRIGHT
        closeX.OnClick = (self.CloseSvc, servicename)
        iconpar.children.append(closeX)
        line = uix.GetLine(iconpar, uix.UI_ALTOP, 1, left=2, top=16, width=18)
        line.anchors = uix.UI_ANCHRIGHT
        line.align = uix.UI_ALNONE
        line.width = 18
        icon.state = uix.UI_DISABLED
        wnd.sr.caption.text = self.GetServiceDisplayName(servicename)
        wnd.sr.caption.state = uix.UI_DISABLED
        return (svc, 'service')



    def CloseSvc(self, *args):
        uthread.new(self.LoadSvc, None)



    def AbortUndock(self, *args):
        sm.GetService('loading').ProgressWnd(mls.UI_STATION_ABORTUNDOCK, '', 1, 1)
        self.dockaborted = 1
        self.exitingstation = 0
        self.LoadLobby()
        sm.GetService('loading').FadeFromBlack()
        sm.GetService('tutorial').UnhideTutorialWindow()



    def Exit(self, *args):
        if self.exitingstation:
            return 
        sm.GetService('michelle').RefreshCriminalFlagCountDown()
        (charcrimes, corpcrimes,) = sm.GetService('michelle').GetCriminalFlagCountDown()
        systemSecStatus = sm.StartService('map').GetSecurityClass(eve.session.solarsystemid2)
        beenWarned = False
        if (charcrimes.has_key(None) and (systemSecStatus == const.securityClassHighSec)):
            response = eve.Message('UndockCriminalConfirm', {}, uix.YESNO)
            beenWarned = True
            if (response != uix.ID_YES):
                return 
        if (charcrimes and (not beenWarned)):
            if (systemSecStatus > const.securityClassZeroSec):
                for (k, v,) in charcrimes.iteritems():
                    if ((k == eve.stationItem.ownerID) or (not util.IsNPC(k))):
                        if (eve.Message('UndockAggressionConfirm', {}, uix.YESNO) == uix.ID_YES):
                            break
                        return 

        self.exitingstation = 1
        self.dockaborted = 0
        activeShip = self.GetActiveShip()
        if not activeShip:
            activeShip = eve.session.shipid
        if not activeShip:
            self.SelectShipDlg()
            if not self.exitingstation:
                return 
        uthread.new(self.LoadSvc, None)
        lobby = self.GetLobby()
        if ((lobby is not None) and (not lobby.destroyed)):
            lobby.SelfDestruct()
        sm.GetService('uipointerSvc').ClearPointers()
        msg = [(mls.UI_STATION_PREPARETOUNDOCK, mls.UI_STATION_REQUESTINGUNDOCK),
         (mls.UI_STATION_PREPARETOUNDOCK, mls.UI_STATION_WAITINGFORCONFIRM),
         (mls.UI_STATION_PREPARETOUNDOCK, mls.UI_STATION_UNDOCKCONFIRMED),
         (mls.UI_STATION_ENTERINGSPACE, mls.UI_STATION_PREPARINGSHIP),
         (mls.UI_STATION_ENTERINGSPACE, mls.UI_STATION_SHIPREADY)]
        minSleepTime = (max((len(msg) * 1000), (((eve.session.nextSessionChange or 0.0) - blue.os.GetTime()) / (SEC / 1000))) / len(msg))
        uthread.new(sm.GetService('loading').FadeToBlack, 4000)
        for i in xrange(len(msg)):
            if self.dockaborted:
                self.exitingstation = 0
                break
            sm.GetService('loading').ProgressWnd(msg[i][0], msg[i][1], (i + 1), (len(msg) + 1), abortFunc=self.AbortUndock)
            blue.pyos.synchro.Sleep(minSleepTime)

        blue.pyos.synchro.Sleep(1000)
        if self.dockaborted:
            self.dockaborted = 0
            return 
        sm.GetService('loading').ProgressWnd(msg[i][0], msg[i][1], (i + 2), (len(msg) + 1))
        if not util.IncarnaNPEEnabled():
            scene = sm.GetService('sceneManager').GetRegisteredScene('default')
            scene.update = 0
        self.UndockAttempt()



    def UndockAttempt(self):
        if not util.IncarnaNPEEnabled():
            scene = sm.GetService('sceneManager').GetRegisteredScene('default')
        systemCheckSupressed = (settings.user.suppress.Get('suppress.FacWarWarningUndock', None) == uix.ID_OK)
        if ((not systemCheckSupressed) and eve.session.warfactionid):
            isSafe = sm.StartService('facwar').CheckForSafeSystem(eve.stationItem, eve.session.warfactionid)
            if not isSafe:
                if not (eve.Message('FacWarWarningUndock', {}, uix.OKCANCEL) == uix.ID_OK):
                    settings.user.suppress.Set('suppress.FacWarWarningUndock', None)
                    self.exitingstation = 0
                    if not util.IncarnaNPEEnabled():
                        scene.update = 1
                    self.AbortUndock()
                    return 
        self.DoUndockAttempt(False, True)



    def DoUndockAttempt(self, ignoreContraband, observedSuppressed = False):
        if util.IncarnaNPEEnabled():
            stationID = session.stationid
        else:
            scene = sm.GetService('sceneManager').GetRegisteredScene('default')
        try:
            shipsvc = sm.GetService('gameui').GetShipAccess()
            sm.GetService('logger').AddText((mls.UI_STATION_UNDOCKINGFROMTO % {'from': cfg.evelocations.Get(eve.session.stationid).name,
             'to': cfg.evelocations.Get(eve.session.solarsystemid2).name}))
            if observedSuppressed:
                ignoreContraband = (settings.user.suppress.Get('suppress.ShipContrabandWarningUndock', None) == uix.ID_OK)
            sm.GetService('sessionMgr').PerformSessionChange('undock', shipsvc.Undock, ignoreContraband)
            self.CloseFitting()
        except Exception, e:
            doRaise = True
            if (isinstance(e, UserError) and (e.msg == 'ShipContrabandWarningUndock')):
                if (eve.Message(e.msg, e.dict, uix.OKCANCEL) == uix.ID_OK):
                    self.DoUndockAttempt(True)
                    sys.exc_clear()
                    return 
                settings.user.suppress.Set('suppress.ShipContrabandWarningUndock', None)
                doRaise = False
            self.exitingstation = 0
            if not util.IncarnaNPEEnabled():
                scene.update = 1
            self.AbortUndock()
            if doRaise:
                raise 
            sys.exc_clear()
        self.exitingstation = 0
        if util.IncarnaNPEEnabled():
            sm.GetService('worldSpaceClient').TearDownWorldSpaceRendering()
            sm.GetService('worldSpaceClient').UnloadWorldSpaceInstance(stationID)
        else:
            scene.update = 1
        self.RemoveFullScreenSprite()



    def CloseFitting(self):
        wnd = sm.GetService('window').GetWindow('fitting')
        if wnd:
            wnd.CloseX()



    def SelectShipDlg(self):
        hangarInv = eve.GetInventory(const.containerHangar)
        items = hangarInv.List()
        tmplst = []
        for item in items:
            if ((item[const.ixCategoryID] == const.categoryShip) and item[const.ixSingleton]):
                tmplst.append((cfg.invtypes.Get(item[const.ixTypeID]).name,
                 item[const.ixItemID],
                 item[const.ixTypeID]))

        if not tmplst:
            self.exitingstation = 0
            eve.Message('NeedShipToUndock')
            return 
        ret = uix.ListWnd(tmplst, 'item', mls.UI_STATION_SELECTSHIP, None, 1)
        if ((ret is None) or (ret[1] == session.shipid)):
            self.exitingstation = 0
            return 
        activeShip = ret[1]
        shipsvc = sm.GetService('gameui').GetShipAccess()
        try:
            sm.GetService('sessionMgr').PerformSessionChange('board', shipsvc.Board, activeShip, (session.shipid if session.shipid else session.stationid))
            self.ShowShip(activeShip)
        except:
            self.exitingstation = 0
            raise 



    def WaitForShip(self, shipID):
        maximumWait = 10000
        sleepUnit = 100
        iterations = (maximumWait / sleepUnit)
        while ((eve.session.shipid != shipID) and iterations):
            iterations -= 1
            blue.pyos.synchro.Sleep(sleepUnit)

        if (eve.session.shipid != shipID):
            raise RuntimeError('Ship never came :(')
        self.LogInfo(('Waited for ship for %d iterations.' % ((maximumWait / sleepUnit) - iterations)))



    def ChangeColorOfActiveShip(self, typeName, colorID, typeID):
        self.previewColorIDs[typeName] = colorID
        sm.services['t3ShipSvc'].ChangeColor(self.activeshipmodel, self.previewColorIDs, typeID)



    def ConfirmChangeColor(self):
        if (self.previewColorIDs is None):
            return 
        eve.GetInventoryFromId(self.activeShip).ChangeColor(self.previewColorIDs)
        eve.Message('ColorOfShipHasBeenChanged')




class StationLayer(uicls.LayerCore):
    __guid__ = 'form.StationLayer'

    def OnCloseView(self):
        sm.GetService('station').CleanUp()



    def OnOpenView(self):
        return 




